package oneD.models;

import oneD.fem.Constraint;
import oneD.fem.Force;
import oneD.fem.Node;
import oneD.fem.structure.Structure;
import oneD.fem.structure.Tensegrity;
import oneD.fem.visualize.TrussVisualizer;
import inf.jlinalg.ArrayVector;
import inf.jlinalg.BLAM;
import inf.jlinalg.IVector;
import inf.v3d.view.Viewer;

public class PrismTensegrity extends ModelViewer {

	@Override
	public Tensegrity createStructure() {
		Tensegrity struct = new Tensegrity();

		double R = 1;
		double H = 2;

		double At = Math.PI * Math.pow(0.02, 2) / 4;
		double Ac = Math.PI * Math.pow(0.01, 2) / 4;

		Node n1 = struct.addNode(0, 0, 0);
		Node n2 = struct.addNode(R * Math.sqrt(3), 0, 0);
		Node n3 = struct.addNode(R * Math.sqrt(3) / 2, R * 3 / 2, 0);
		Node n4 = struct.addNode(R * (1 + Math.sqrt(3) / 2), R / 2, H);
		Node n5 = struct.addNode(R * (-1 + Math.sqrt(3)) / 2,
				R * (1 + Math.sqrt(3)) / 2, H);
		Node n6 = struct.addNode(R * (-1 + Math.sqrt(3)) / 2,
				R * (1 - Math.sqrt(3)) / 2, H);

		struct.addTrussElement(1, 2e7, At, 0, 0, 3);
		struct.addTrussElement(1, 2e7, At, 0, 1, 4);
		struct.addTrussElement(1, 2e7, At, 0, 2, 5);
		// struct.addCableElement(0.1, 2e3, Ac, 10e3 / Ac, 0, 1);
		// struct.addCableElement(0.1, 2e3, Ac, 10e3 / Ac, 1, 2);
		// struct.addCableElement(0.1, 2e3, Ac, 10e3 / Ac, 0, 2);
		// struct.addCableElement(0.1, 2e3, Ac, 10*10e3 / Ac, 3, 4);
		// struct.addCableElement(0.1, 2e3, Ac, 10*10e3 / Ac, 4, 5);
		// struct.addCableElement(0.1, 2e3, Ac, 10*10e3 / Ac, 3, 5);
		// struct.addCableElement(0.1, 2e3, Ac, Math.sqrt(3) * 10e3 / Ac, 0, 5);
		// struct.addCableElement(0.1, 2e3, Ac, Math.sqrt(3) * 10e3 / Ac, 1, 3);
		// struct.addCableElement(0.1, 2e3, Ac, Math.sqrt(3) * 10e3 / Ac, 2, 4);
		struct.addCableElement(0.1, 2e3, Ac, 10e3 / Ac, 0, 1);
		struct.addCableElement(0.1, 2e3, Ac, 0, 1, 2);
		struct.addCableElement(0.1, 2e3, Ac, 0, 0, 2);
		struct.addCableElement(0.1, 2e3, Ac, 0, 3, 4);
		struct.addCableElement(0.1, 2e3, Ac, 10e0 / Ac, 4, 5);
		struct.addCableElement(0.1, 2e3, Ac, 10e0 / Ac, 3, 5);
		struct.addCableElement(0.1, 2e3, Ac, 10e3 / Ac, 0, 5);
		struct.addCableElement(0.1, 2e3, Ac, 10e3 / Ac, 1, 3);
		struct.addCableElement(0.1, 2e3, Ac, 10e3 / Ac, 2, 4);

		Constraint c1 = new Constraint(false, false, false);
		Constraint c2 = new Constraint(true, false, false);
		Constraint c3 = new Constraint(true, true, false);

		n1.setConstraint(c1);
		n2.setConstraint(c2);
		n3.setConstraint(c3);

		Force f = new Force(100e5, 0, 0);

		n4.setForce(f);

		return struct;
	}

	@Override
	public void initializeVisualizer(Structure struct) {
		this.view_ = new Viewer();
		viz_ = new TrussVisualizer(struct, this.view_);
	}

	@Override
	protected void performLinearModalAnalysis(Structure struct) {
		/*
		 * perform linear modal analysis
		 */
		System.out
				.println("This functionality is not supported for this model");
	}

	@Override
	protected void performNonlinearInstabilityAnalysisUsingDirectComputation(
			Structure struct) {
		/*
		 * instability analysis using direct computation
		 */
		double lambda = 1;
		IVector phi = new ArrayVector(struct.enumerateDOFs());
		BLAM.fill(phi, 0.1);
		IVector u = struct.createZeroU();
		struct.directLoadControlInstabilityComputation(u, lambda, phi);
	}
	
	public static void main(String[] args) {
		PrismTensegrity model = new PrismTensegrity();
		model.processUserInput();
	}
}
